package data.result;


import data.cad.CAD;
import data.component.Ceiling;
import data.component.Wall;
import data.xml.XML;
import utils.Geometry;
import utils.Matrix;

import java.util.*;
import java.util.stream.Collectors;

// 指标测量信息
public class MeasureItem {
    /**
     * 测量项ID
     */
    public String id;

    /**
     * 测量值
     */
    public ArrayList<MeasureValue> points;

    /**
     * 图纸ID
     */
    public String drawMapId;

    /**
     * 匹配分数
     */
    public double matchScore;

    /**
     * 原始墙号（适用多墙测量项）
     */
    public ArrayList<String> walls;

    public void SetMeasureItem(CAD cad, XML xml, HashMap<String, Wall> map,  Matrix m, Double angle) {

        this.points.forEach(p -> p.SetMeasureValue(cad,this.id, m, angle));

        FilterPoints(cad.room.contours);

        var cornerItem = Set.of("4","6", "74", "73");

        var multiWallItem = Set.of("7", "8", "9", "N/A", "10");

        var singleWallItem = Set.of("72", "3", "51", "56");

        var openingItem = Set.of("903", "904", "902", "901");

        if (this.id.equals("6") && this.walls != null)
        {
           SetDrawMapId(xml.ceilings);
        }

        if (multiWallItem.contains(this.id))
        {
            var mapWall1 = CAD.GetLongestMappingWallByXmlWallId(cad.walls, map, this.walls.get(0));
            var mapWall2 = CAD.GetLongestMappingWallByXmlWallId(cad.walls, map, this.walls.get(1));
            if (mapWall1 != null && mapWall2!= null) {
                this.setDrawMapId(mapWall1.id, mapWall2.id);
                setMatchScore(mapWall1, mapWall2, map);
            }
        }

    }

    public void SetMeasureItem(CAD cad, HashMap<String, Wall> map,  Matrix m, Double angle) {

        this.points.forEach(p -> p.SetMeasureValue(cad,this.id, m, angle));

        FilterPoints(cad.room.contours);

        var cornerItem = Set.of("4","6", "74", "73");

        var multiWallItem = Set.of("7", "8", "9", "N/A", "10");

        var singleWallItem = Set.of("72", "3", "51", "56");

        var openingItem = Set.of("903", "904", "902", "901");

        if (multiWallItem.contains(this.id))
        {
            var mapWall1 = CAD.GetLongestMappingWallByXmlWallId(cad.walls, map, this.walls.get(0));
            var mapWall2 = CAD.GetLongestMappingWallByXmlWallId(cad.walls, map, this.walls.get(1));
            if (mapWall1 != null && mapWall2!= null)
            {
                this.setDrawMapId(mapWall1.id, mapWall2.id);
                setMatchScore(mapWall1, mapWall2, map);
            }
        }

    }


    public void SetMeasureItem(CAD cad, HashMap<String, Wall> map, Matrix m, Double angle, String drawMapId, Double matchScore)
    {
        this.points.forEach(p -> p.SetMeasureValue(this.id, m, this.matchScore, angle));

        FilterPoints(cad.room.contours);

        if (drawMapId != null)
            SetDrawMapId(drawMapId);
        if (matchScore != null && matchScore != 0d)
            SetMatchScore(matchScore);
    }

    private void SetDrawMapId(String drawMapId) {
        this.drawMapId = drawMapId;
    }

    private void setDrawMapId(String mapWallId1, String mapWallId2) {
        this.drawMapId = mapWallId1 + "_" + mapWallId2;
    }

    private void SetDrawMapId(List<Ceiling> ceilings)
    {
        var filterCeilings = ceilings.stream().filter(ceiling -> ceiling.id.equals(this.walls.get(0))).collect(Collectors.toList());
        if (!filterCeilings.isEmpty()){
            this.drawMapId = ceilings.get(0).code;
        }
    }

    private void SetMatchScore(Double matchScore) {
        this.matchScore = matchScore;
    }

    private void setMatchScore(Wall mapWall1, Wall mapWall2, HashMap<String, Wall> map) {
//        var score1 = mapWall1!=null && map.get(mapWall1.id) != null ? map.get(mapWall1.id).scanQuality : 0;
//        var score2 = mapWall2!=null && map.get(mapWall2.id) != null ? map.get(mapWall2.id).scanQuality : 0;
//        this.matchScore = score1 + score2;
        this.matchScore = Math.random();
    }


//    private void SetPoints(Matrix m, Double angle) {
//
//        this.points.forEach(p -> p.SetMeasureValue(this.id, m, this.matchScore, angle));
//    }

    private void FilterPoints(ArrayList<Double[]> contours) {
        var longWidthItem = new ArrayList<>(Arrays.asList("8", "9", "913", "914", "915", "916"));
        for (int i = this.points.size() - 1; i >= 0; i--) {
            if (longWidthItem.contains(this.id) || points.get(i).cadCoordinate == null || Geometry.IsPointInPolygon(points.get(i).cadCoordinate, contours))
                continue;
            this.points.remove(i);
        }
    }
}
